home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dcc / save / main.cok < prev   
Encoding:
Text File  |  1993-06-28  |  43.4 KB  |  2,302 lines

  1.  
  2. /*
  3.  *  MAIN.C
  4.  *
  5.  *  (c)Copyright 1990, Matthew Dillon, All Rights Reserved
  6.  *
  7.  *  dcc <options> <files>
  8.  */
  9.  
  10. #include "defs.h"
  11. #ifdef COMMERCIAL
  12. #ifndef unix
  13. #include <lib/rexx.h>
  14. #endif
  15. #endif
  16.  
  17. #ifndef AZLAT_COMPAT
  18. #define DoLink_Dice    DoLink
  19. #define DoCompile_Dice    DoCompile
  20. #define DoAssemble_Dice DoAssemble
  21. #define DoPrelink_Dice    DoPrelink
  22. #endif
  23.  
  24. #ifdef _DCC
  25. IDENT("DCC",".58");
  26. DCOPYRIGHT;
  27. #endif
  28.  
  29. Prototype   void    myexit(void);
  30. Prototype   int     main(int, char **);
  31. Prototype   void    AddFile(char *);
  32. Prototype   void    help(int);
  33. Prototype   char    *TmpFileName(char *);
  34. Prototype   char    *MungeFile(char *, char *, char *);
  35. Prototype   void    AddName(List *, char *, char *, short);
  36. Prototype   struct NameNode *AddOpt(List *, char *, char *);
  37. Prototype   char    *Tailer(char *);
  38. Prototype   char    *XFilePart(char *);
  39. Prototype   char    *OptListToStr(List *);
  40. Prototype   char    *OptListToStr2(List *, char *);
  41. Prototype   void    run_cmd(char *, char *);
  42. Prototype   int     OutOfDate(char *, char *);
  43. Prototype   void    HandleCFile(struct NameNode *, int);
  44. Prototype   void    HandleAFile(struct NameNode *, int);
  45. Prototype   void    PushTmpFile(char *);
  46. Prototype   void    PopTmpFile(char *);
  47. Prototype   long    LoadSegLock(long, char *);
  48. Prototype   void    DefaultOutName(void);
  49.  
  50. Prototype   int     DoCompile(char *, char *);
  51. Prototype   int     DoCompile_Dice(char *, char *);
  52. Prototype   int     DoCompile_Aztec(char *, char *);
  53. Prototype   int     DoCompile_Lattice(char *, char *);
  54. Prototype   int     DoAssemble(char *, char *, char *);
  55. Prototype   int     DoAssemble_Dice(char *, char *, char *);
  56. Prototype   int     DoAssemble_Aztec(char *, char *, char *);
  57. Prototype   int     DoAssemble_Lattice(char *, char *, char *);
  58. Prototype   char    *DoPrelink(void);
  59. Prototype   char    *DoPrelink_Dice(void);
  60. Prototype   char    *DoPrelink_Aztec(void);
  61. Prototype   char    *DoPrelink_Lattice(void);
  62. Prototype   int     DoLink(char *);
  63. Prototype   int     DoLink_Dice(char *);
  64. Prototype   int     DoLink_Aztec(char *);
  65. Prototype   int     DoLink_Lattice(char *);
  66. Prototype   char    *PathConvert(char *);
  67. Prototype   void    *GetHead(List *);
  68. Prototype   void    *GetSucc(Node *);
  69. Prototype   int     HandleErrorRexx(char *, char *, int);
  70. Prototype   char    *ScanReplace(char *, char *, char *, char *);
  71. Prototype   char    *FullPathOf(char *);
  72. Prototype   char    *mergestr(const char *s1, const char *s2);
  73.  
  74. void OrderApp(char *);
  75. void AddLibApp(char *, char);
  76. void DelLibApp(char *, char);
  77.  
  78. /*
  79.  *  Note that we use exec_dcc if DCC, which only works with 'dcc' programs
  80.  *  thus, the executables are renamed to prevent problems.
  81.  */
  82.  
  83. Prototype __aligned char Buf[512];
  84. Prototype __aligned char CmdName[64];
  85.  
  86.  
  87. __aligned char Buf[512];
  88. __aligned char CmdName[64];
  89. char TmpFile[64];
  90. char ErrOptStr[128];
  91. char *ErrFile;
  92. char *OutFile;
  93. char *OutDir = NULL;
  94. #ifdef AMIGA
  95. char *TmpDir = "T:";
  96. #else
  97. char *TmpDir = "/tmp/";
  98. #endif
  99. char *DLib;
  100. char *AmigaLib;
  101. char *CLib;
  102. char ALibOS[4];
  103. char ALibApp[32] = { "s" };
  104. char CLibApp[32] = { "s" };
  105. char *RexxReplace[10];
  106. List TmpList;
  107. short ErrFileIsTmp;
  108. short NewOpt;
  109. short FastOpt;
  110. short FragOpt;
  111. short ChipOpt;
  112. short MC68020Opt;
  113. short MC68881Opt;
  114. short FFPOpt;
  115. short DDebug;
  116. short RegCallOpt;
  117. short NoHeirOpt;
  118. short NoEnvOpt;
  119. short NoCtlOpt;
  120. short SlashSlashOpt;
  121. short ProfOpt;
  122. short DLinkPostFixOpt;
  123. short UnixOpt;
  124. short ForkOpt;
  125. short UnixCommonOpt;
  126. short InlineCompOpt;
  127. short RexxOpt;
  128.  
  129. long    ExitCode;
  130.  
  131. char DLINK[32];
  132. char DAS[32];
  133. char DC1[32];
  134. char DCPP[32];
  135.  
  136. char *RexxHostName = "DCC";
  137.  
  138. char *SCode[4];
  139. char *IntOpt = "";
  140.  
  141.  
  142. typedef struct NameNode {
  143.     struct Node n_Node;
  144.     char    *n_In;
  145.     char    *n_Out;
  146.     short   n_IsType;
  147. } NameNode;
  148.  
  149. #define IS_CFILE    1
  150. #define IS_AFILE    2
  151. #define IS_OFILE    3
  152. #define IS_LIBFILE  4
  153. #define IS_TMP        0x100
  154. #define IsMask(istype) ((ubyte)istype)
  155.  
  156. List   FList;
  157. List   LList;
  158.  
  159. List   CppOptList;
  160. List   LinkOptList;
  161.  
  162. short    NoLink;
  163. short    NoAsm;
  164. short    SmallCode = 1;
  165. short    SmallData = 1;
  166. short    ConstCode;        /*    -ms            */
  167. short    AbsData;        /*    -mw, -ma        */
  168. short    ResOpt;
  169. short    AltSectOpt;
  170. short    SymOpt;
  171. short    RomOpt;
  172. short    ProtoOnlyOpt;
  173. short    NoIntermediateAssembly;
  174. short    PIOpt;
  175. short    GenStackOpt;
  176. short    GenLinkOpt;
  177. short    Verbose;
  178. short    NoDefaultLibs;
  179. short    CompilerOpt = DICE_C;
  180. long    AbsDataStart;        /*    -mw <addr>  */
  181. char    DebugOpts[64];
  182.  
  183. NameNode *InlineNode;
  184.  
  185. extern struct Library *SysBase;
  186.  
  187. void
  188. myexit()
  189. {
  190.     Node *node;
  191.  
  192.     while (node = RemHead(&TmpList)) {
  193.     remove(node->ln_Name);
  194.     free(node);
  195.     }
  196.  
  197. #if 0
  198.     if (ErrFileIsTmp) {
  199.     fclose(stderr);
  200.     remove(ErrFile);
  201.     }
  202. #endif
  203. }
  204.  
  205. int
  206. main(xac, xav)
  207. int xac;
  208. char *xav[];
  209. {
  210.     int fc = 0;
  211.     int ac;
  212.     char **av;
  213.  
  214.  
  215. #ifdef LATTICE
  216.     {
  217.     long n = (long)Buf;
  218.     if (n & 3) {
  219.         puts("software error, Buf not aligned");
  220.         exit(25);
  221.     }
  222.     }
  223. #endif
  224. #ifdef NOTDEF
  225.     expand_args(xac, xav, &ac, &av);
  226. #else
  227.     ac = xac;
  228.     av = xav;
  229. #endif
  230.  
  231.     NewList(&FList);
  232.     NewList(&LList);
  233.  
  234.     NewList(&TmpList);
  235.  
  236.     NewList(&CppOptList);
  237.     NewList(&LinkOptList);
  238.  
  239.     atexit(myexit);
  240.  
  241.     if (ac == 1)
  242.     help(0);
  243.  
  244.     {
  245.     char *ptr = av[0];    /*  cmd name */
  246.     char prefix[32];
  247.     short i;
  248.  
  249.     for (i = strlen(ptr); i >= 0 && ptr[i] != ':' && ptr[i] != '/'; --i);
  250.     ++i;
  251.  
  252.     ptr = ptr + i;        /*  base name */
  253.     for (i = 0; ptr[i] && ptr[i] != '_'; ++i);
  254.     if (ptr[i] == '_') {
  255.         strncpy(prefix, ptr, i + 1);
  256.         prefix[i+1] = 0;
  257.     } else {
  258.         prefix[0] = 0;
  259.     }
  260.     sprintf(DLINK, "%s%s", prefix, "dlink");
  261.     sprintf(DAS  , "%s%s", prefix, "das");
  262.     sprintf(DC1  , "%s%s", prefix, "dc1");
  263.     sprintf(DCPP , "%s%s", prefix, "dcpp");
  264.     DLib = mergestr(DLIBPRE, prefix);
  265.     DLib = mergestr(DLib, DLIBPOS);
  266.     }
  267.     AmigaLib = mergestr(DLib, "amiga");
  268.     CLib = mergestr(DLib, "c");
  269.  
  270.     /*
  271.      *  2 x PIOpt + ResOpt
  272.      */
  273.  
  274.     SCode[0] = mergestr(DLib, "c.o");
  275.     SCode[1] = mergestr(DLib, "c.o");
  276.     SCode[2] = mergestr(DLib, "c_pi.o");
  277.     SCode[3] = mergestr(DLib, "c_pr.o");
  278.  
  279.     /*
  280.      *    check for -no-env option before processing DCCOPTS enviroment var
  281.      *    check for -no-ctl option before processing DCCOPTS file
  282.      */
  283.  
  284.     {
  285.     long i;
  286.  
  287.     for (i = 1; i < ac; ++i) {
  288.         if (strcmp(av[i], "-no-env") == 0) {
  289.         NoEnvOpt = 1;
  290.         break;
  291.         }
  292.         if (strcmp(av[i], "-no-ctl") == 0) {
  293.         NoCtlOpt = 1;
  294.         break;
  295.         }
  296.     }
  297.     }
  298.  
  299.     if (NoEnvOpt == 0) {
  300.     char **argv = av;
  301.     ac = ExtArgsEnv(ac, &argv, "DCCOPTS");
  302.     av = argv;
  303.     }
  304.     if (NoCtlOpt == 0) {
  305.     char **argv = av;
  306.     ac = ExtArgsFile(ac, &argv, "DCCOPTS");
  307.     av = argv;
  308.     }
  309.  
  310.     {
  311.     long i;
  312.     char *dummy;
  313.  
  314.     for (i = 1; i < ac; ++i) {
  315.         char *ptr = av[i];
  316.  
  317.         if (*ptr == '-') {
  318.         ptr += 2;
  319.  
  320.         switch(ptr[-1]) {
  321.         case '0':       /*  -020/-030/-040      */
  322.             MC68020Opt = 1;
  323.             break;
  324.         case '1':       /*  1.4, 1.3    */
  325.         case '2':       /*  2.0, 2.1..  */
  326.         case '3':
  327.         case '4':
  328.         case '5':
  329.             if (ptr[0] != '.')
  330.             help(1);
  331.             AddOpt(&CppOptList, ptr - 2, "");
  332.             ALibOS[0] = ptr[-1];
  333.             ALibOS[1] = ptr[1];
  334.             break;
  335.         case '8':
  336.             MC68881Opt = 1;
  337.             break;
  338.         case 'f':
  339.             if (*ptr == 0)
  340.             FastOpt = 1;
  341.             else if (*ptr == '0')
  342.             FastOpt = 0;
  343.             else if (*ptr == 'r') {
  344.             if (stricmp(ptr, "rag0") == 0)
  345.                 FragOpt = 0;
  346.             else
  347.                 FragOpt = 1;
  348.             } else if (*ptr == 'f')
  349.             FFPOpt = 1;
  350.             else if (*ptr == 'o') {
  351.             ForkOpt = 1;
  352.             AddLibApp(CLibApp, 'f');
  353.             }
  354.             break;
  355.         case 'i':   /*  -ieee   */
  356.             if (*ptr == 'e')
  357.             FFPOpt = 0;
  358.             else if (strncmp(ptr, "nt", 2) == 0) {
  359.             IntOpt = (ptr[2]) ? ptr + 2 : av[++i];
  360.             }
  361.             break;
  362.         case 'r':
  363.             if (strcmp(ptr, "om") == 0) {
  364.             RomOpt = 1;
  365.             } else if (*ptr == '0') {
  366.             ResOpt = 0;
  367.             } else {
  368.             if (PIOpt && ResOpt == 0)
  369.                 puts("DCC: Warning, -r -pi = -pr");
  370.             ResOpt = 1;
  371.             }
  372.             break;
  373.         case 'c':
  374.             if (*ptr == 0)
  375.             NoLink = 1;
  376.             else if (stricmp(ptr, "hip") == 0)
  377.             ChipOpt = 1;
  378.             else if (stricmp(ptr, "hip0") == 0)
  379.             ChipOpt = 0;
  380.             else
  381.             help(1);
  382.             break;
  383.         case 'a':
  384.             if (strcmp(ptr, "ztec") == 0) {
  385.             CompilerOpt = AZTEC_C;
  386.             break;
  387.             }
  388.             NoAsm = 1;
  389.             NoLink= 1;
  390.             break;
  391.         case 'g':
  392.             switch (*ptr) {
  393.             case 's':
  394.             GenStackOpt = 1;
  395.             if (ptr[1] == '0')
  396.                 GenStackOpt = 0;
  397.             break;
  398.             case 'l':
  399.             GenLinkOpt = 1;
  400.             break;
  401.             default:
  402.             help(1);
  403.             }
  404.             break;
  405.         case 'l':
  406.             if (strcmp(ptr, "attice") == 0) {
  407.             CompilerOpt = LATTICE_C;
  408.             break;
  409.             }
  410.             if (ptr[0] == '0' && ptr[1] == 0) {
  411.             NoDefaultLibs = 1;
  412.             break;
  413.             }
  414.             if (*ptr == 0)
  415.             ptr = av[++i];
  416.             AddName(&LList, ".lib", ptr, IS_LIBFILE);
  417.             DLinkPostFixOpt = 1;
  418.             break;
  419.         case 'L':   /*  -Ldir   */
  420.             if (ptr[0] == '0' && ptr[1] == 0) {
  421.             AddOpt(&LinkOptList, "-L0", "");
  422.             break;
  423.             }
  424.             if (*ptr == 0)
  425.             ptr = av[++i];
  426.             AddOpt(&LinkOptList, "-L", PathConvert(ptr));
  427.             break;
  428.         case 'I':   /*  -Idir   */
  429.             if (ptr[0] == '0' && ptr[1] == 0) {
  430.             AddOpt(&CppOptList, "-I0", "");
  431.             break;
  432.             }
  433.             if (*ptr == 0)
  434.             ptr = av[++i];
  435.             AddOpt(&CppOptList, "-I", PathConvert(ptr));
  436.             break;
  437.         case 'd':   /*  -dice -d<n> -d<debug_opts>  */
  438.             /*
  439.              *    note that -d<n> and -s<n> are mutually
  440.              *    exclusive in that -d1 implies -s and -s0
  441.              *    implies -d0
  442.              */
  443.  
  444.             if (strcmp(ptr, "ice") == 0) {
  445.             CompilerOpt = DICE_C;
  446.             break;
  447.             }
  448.             sprintf(DebugOpts, " -d%s", ptr);
  449.  
  450. #ifdef LATTICE
  451.             switch(atoi(ptr)) {
  452. #else
  453.             switch(strtol(ptr, NULL, 0)) {
  454. #endif
  455.             case 0:
  456.             SymOpt = 0;
  457.             break;
  458.             default:
  459.             SymOpt = 1;
  460.             }
  461.             break;
  462.         case 'Z':
  463.             if (atoi(ptr)) {
  464.             DDebug = atoi(ptr);
  465.             break;
  466.             }
  467.             break;
  468.         case 'D':   /*  -Ddefine[=str] */
  469.             if (*ptr == 0)
  470.             ptr = av[++i];
  471.             AddOpt(&CppOptList, "-D", ptr);
  472.             break;
  473.         case 'H':   /*  -H<path>=<include_name>    */
  474.             if (*ptr == 0)
  475.             ptr = av[++i];
  476.             AddOpt(&CppOptList, "-H", ptr);
  477.             break;
  478.         case 'u':
  479.             if (strcmp(ptr, "nix") == 0) {
  480.             UnixOpt = 1;
  481.             CLib = mergestr(DLib, "uc");
  482.             AddOpt(&CppOptList, "-unix", "");
  483.             }
  484.             break;
  485.         case 'U':   /*  -U      -undefine certain symbols */
  486.             AddOpt(&CppOptList, "-U", ptr);
  487.             break;
  488.         case 'o':
  489.             if (*ptr)
  490.             OutFile = PathConvert(ptr);
  491.             else
  492.             OutFile = PathConvert(av[++i]);
  493.             {
  494.             short idx = strlen(OutFile) - 2;
  495.             if (idx >= 0) {
  496.                 if (stricmp(OutFile + idx, ".h") == 0 || stricmp(OutFile + idx, ".c") == 0) {
  497.                 puts("ERROR! -o output file may not end in .c or .h!");
  498.                 exit(20);
  499.                 }
  500.             }
  501.             }
  502.             break;
  503.         case 'O':
  504.             if (strcmp(ptr, "0") == 0)
  505.             OutDir = NULL;
  506.             else if (*ptr)
  507.             OutDir = PathConvert(ptr);
  508.             else
  509.             OutDir = PathConvert(av[++i]);
  510.             break;
  511.         case 'E':   /*  error output append */
  512.             {
  513.             char errtype = '1';
  514.             if (*ptr >= '1' && *ptr <= '9')
  515.             {
  516.                 errtype = *ptr;
  517.                 ptr++;
  518.             }
  519.             if (*ptr == 0)
  520.             ptr = av[++i];
  521.  
  522. #if 0
  523.             if (freopen(ptr, "a", stderr)) {
  524.                 if (ErrFile)
  525.                 remove(ErrFile);
  526.                 ErrFile = ptr;
  527.                 ErrFileIsTmp = 0;
  528.                 sprintf(ErrOptStr, " -E%c %s", errtype, ptr);
  529.             } else {
  530.                 printf("unable to append to %s\n", ptr);
  531.             }
  532. #endif
  533.             }
  534.             break;
  535.         case 'p':
  536.             if (strcmp(ptr, "roto") == 0) {
  537.             ProtoOnlyOpt = 1;
  538.             } else if (strncmp(ptr, "rof", 3) == 0) {
  539.             if (ptr[3] != '0') {
  540.                 ProfOpt = atoi(ptr + 3);
  541.                 if (ProfOpt == 0)
  542.                 ProfOpt = 1;
  543.                 if (ProfOpt >= 2)
  544.                 AddLibApp(CLibApp, 'p');
  545.                 if (ProfOpt >= 3)
  546.                 AddLibApp(ALibApp, 'p');
  547.             } else {
  548.                 ProfOpt = 0;
  549.                 DelLibApp(ALibApp, 'p');
  550.                 DelLibApp(CLibApp, 'p');
  551.             }
  552.             } else if (strcmp(ptr, "i") == 0) {
  553.             PIOpt = 1;
  554.             if (ResOpt)
  555.                 puts("DCC: Warning, -r -pi = -pr");
  556.             } else if (strcmp(ptr, "r") == 0) {
  557.             PIOpt = 1;
  558.             ResOpt = 1;
  559.             } else {
  560.             help(1);
  561.             }
  562.             break;
  563.         case 'T':
  564.             if (*ptr)
  565.             TmpDir = PathConvert(ptr);
  566.             else
  567.             TmpDir = PathConvert(av[++i]);
  568.             break;
  569.         case 'm':
  570.             switch(*ptr) {
  571.             case 'C':
  572.             SmallCode = 0;
  573.             break;
  574.             case 'c':
  575.             SmallCode = 1;
  576.             break;
  577.             case 'D':
  578.             SmallData = 0;
  579.             DelLibApp(ALibApp, 's');
  580.             DelLibApp(CLibApp, 's');
  581.             AddLibApp(ALibApp, 'l');
  582.             AddLibApp(CLibApp, 'l');
  583.             break;
  584.             case 'd':
  585.             SmallData = 1;
  586.             DelLibApp(ALibApp, 'l');
  587.             DelLibApp(CLibApp, 'l');
  588.             AddLibApp(ALibApp, 's');
  589.             AddLibApp(CLibApp, 's');
  590.             break;
  591.             case 'a':
  592.             case 'w':
  593.             if (ptr[1] == 'a') {
  594.                 AbsData = 0;
  595.                 AbsDataStart = 0;
  596.             } else {
  597.                 AbsData = 1;
  598.  
  599.                 if (*ptr == 'a')
  600.                 AbsData = 2;
  601.  
  602.                 ++ptr;
  603.                 if (*ptr == 0)
  604.                 ptr = av[++i];
  605.  
  606. #ifdef LATTICE
  607.                 AbsDataStart = atoi(ptr);    /*  bug in lattice */
  608. #else
  609.                 AbsDataStart = strtol(ptr, &dummy, 0);
  610. #endif
  611.             }
  612.             break;
  613.             case 'r':
  614.             RegCallOpt = 1;
  615.             break;
  616.             case 'R':
  617.             AddLibApp(CLibApp, 'r');
  618.             AddLibApp(ALibApp, 'r');
  619.  
  620.             RegCallOpt = 2;
  621.             if (ptr[1] == 'R') {
  622.                 ProtoOnlyOpt = -1;    /*  force prototypes */
  623.                 RegCallOpt = 3;
  624.  
  625.                 switch(ptr[2]) {
  626.                 case 'X':
  627.                 RegCallOpt = 4;
  628.                 break;
  629.                 case 'Y':
  630.                 RegCallOpt = 5;
  631.                 break;
  632.                 case '0':
  633.                 RegCallOpt = 0;
  634.                 if (ProtoOnlyOpt == -1)
  635.                     ProtoOnlyOpt = 0;
  636.                 break;
  637.                 }
  638.             }
  639.             break;
  640.             case 's':
  641.             if (ptr[1])
  642.                 ConstCode = ptr[1] - '0';
  643.             else
  644.                 ConstCode = 1;
  645.             break;
  646.             case 'S':
  647.             /* XXX REMOVED */
  648.             /*ConstCode = 2;*/
  649.             break;
  650.             case 'u':
  651.             UnixCommonOpt = 1;
  652.             break;
  653.             case 'i':
  654.             if (ptr[1] == '0') {
  655.                 if (InlineCompOpt && InlineNode) {
  656.                 InlineCompOpt = 0;
  657.                 Remove(&InlineNode->n_Node);
  658.                 InlineNode = NULL;
  659.                 }
  660.             } else {
  661.                 if (InlineCompOpt == 0) {
  662.                 InlineCompOpt = 1;
  663.                 InlineNode = AddOpt(&CppOptList, "-D", "__DICE_INLINE");
  664.                 }
  665.             }
  666.             break;
  667.             default:
  668.             fprintf(stderr, "DCC: bad -m model\n");
  669.             exit(20);
  670.             }
  671.             break;
  672.         case 'R':
  673. #ifdef COMMERCIAL
  674. #ifndef unix
  675.             /* substitution variables */
  676.  
  677.             if (*ptr >= '0' && *ptr <= '9')
  678.             RexxReplace[*ptr - '0'] = (ptr[1]) ? ptr + 1 : av[++i];
  679.  
  680.             /* rexx system up?    */
  681.  
  682. #if 0
  683.             if (RexxSysBase) {
  684.             RexxOpt = 1;
  685.             if (ErrFile == NULL) {
  686.                 char *ptr = TmpFileName(".e");
  687.  
  688.                 if (freopen(ptr, "a", stderr)) {
  689.                 ErrFile = ptr;
  690.                 ErrFileIsTmp = 1;
  691.                 sprintf(ErrOptStr," -EE %s", ptr);
  692.                 } else {
  693.                 printf("unable to append to %s\n", ptr);
  694.                 }
  695.             }
  696.             } else {
  697.             fprintf(stderr, "DCC: Warning: could open rexxsyslib.library!\n");
  698.             }
  699. #endif
  700. #endif
  701. #endif
  702.             break;
  703.         case 's':
  704.             if (strcmp(ptr, "as") == 0) {
  705.             CompilerOpt = LATTICE_C;
  706.             } else if (*ptr == '0') {
  707.             SymOpt = 0;
  708.             DebugOpts[0] = 0;
  709.             } else {
  710.             SymOpt = 1;
  711.             }
  712.             break;
  713.         case 'S':
  714.             if (*ptr == '0')
  715.             AltSectOpt = 0;
  716.             else
  717.             AltSectOpt = 1;
  718.             break;
  719.         case 'v':
  720.             if (*ptr == '0')
  721.             Verbose = 0;
  722.             else
  723.             Verbose = 1;
  724.             break;
  725.         case '/':
  726.             if (*ptr == '/') {
  727.             if (ptr[1] == '0')
  728.                 SlashSlashOpt = 0;
  729.             else
  730.                 SlashSlashOpt = 1;
  731.             break;
  732.             }
  733.             goto def;
  734.         case 'n':
  735.             if (strcmp(ptr, "ew") == 0) {
  736.             NewOpt = 1;
  737.             break;
  738.             }
  739.             if (strcmp(ptr, "ew0") == 0) {
  740.             NewOpt = 0;
  741.             break;
  742.             }
  743.             if (strcmp(ptr, "oheir") == 0) {
  744.             NoHeirOpt = 1;
  745.             break;
  746.             }
  747.             if (strcmp(ptr, "orom") == 0) {
  748.             RomOpt = 0;
  749.             break;
  750.             }
  751.             if (strcmp(ptr, "oproto") == 0) {
  752.             ProtoOnlyOpt = 0;
  753.             break;
  754.             }
  755.             if (strcmp(ptr, "o-env") == 0)
  756.             break;
  757.             if (strcmp(ptr, "o-ctl") == 0)
  758.             break;
  759.             /* fall through */
  760.         default:
  761.         def:
  762.             fprintf(stderr, "DCC: bad - option\n");
  763.             help(1);
  764.         }
  765.         continue;
  766.         }
  767.         if (*ptr == '+') {
  768.         ptr += 2;
  769.  
  770.         switch(ptr[-1]) {
  771.         case 'I':   /*  +Idir   */
  772.             if (*ptr == 0)
  773.             ptr = av[++i];
  774.             AddOpt(&CppOptList, "+I", ptr);
  775.             break;
  776.         default:
  777.             fprintf(stderr, "DCC: bad + option\n");
  778.             help(1);
  779.         }
  780.         continue;
  781.         }
  782.         if (*ptr == '@') {
  783.         FILE *fi = fopen(ptr + 1, "r");
  784.         char buf[128];
  785.  
  786.         if (fi == NULL) {
  787.             printf("unable to open %s\n", ptr + 1);
  788.             exit(10);
  789.         }
  790.         while (fgets(buf, sizeof(buf), fi)) {
  791.             short len = strlen(buf);
  792.             if (len > 0)
  793.             buf[len-1] = 0;
  794.             if (buf[0] && buf[0] != ';' && buf[0] != '#') {
  795.             ++fc;
  796.             AddFile(buf);
  797.             }
  798.         }
  799.         fclose(fi);
  800.         continue;
  801.         }
  802.         ++fc;
  803.         AddFile(PathConvert(ptr));
  804.     }
  805.     if (i > ac) {
  806.         fprintf(stderr, "DCC: file argument missing\n");
  807.         help(1);
  808.     }
  809.     }
  810.  
  811. #ifdef AZLAT_COMPAT
  812.     if (CompilerOpt == AZTEC_C) {
  813.     puts("DCC in AZTEC mode");
  814.     FastOpt = 0;
  815.     NoIntermediateAssembly = 1;
  816.     }
  817.     if (CompilerOpt == LATTICE_C) {
  818.     puts("DCC in LATTICE mode");
  819.     FastOpt = 0;
  820.     NoIntermediateAssembly = 1;
  821.     }
  822. #else
  823.     if (CompilerOpt != DICE_C)
  824.     puts("DCC must be recompiled w/ AZLAT_COMPAT defined");
  825. #endif
  826.  
  827.     /*
  828.      *    Ensure CLibApp and ALibApp ordering and remove duplicates
  829.      */
  830.  
  831.     OrderApp(CLibApp);
  832.     OrderApp(ALibApp);
  833.  
  834.     /*
  835.      *    If this run is to generate an executable,
  836.      *
  837.      *    (a) determine the name of the executable and
  838.      *    (b) delete it before compiling anything
  839.      */
  840.  
  841.     if (NoLink == 0) {
  842.     DefaultOutName();    /*  default output name     */
  843.     remove(OutFile);    /*  make sure it's deleted  */
  844.     }
  845.  
  846.     /*
  847.      *    Compile sources into assembly
  848.      *    Assemble assembly into objects
  849.      *    Link objects into executable
  850.      */
  851.  
  852.     {
  853.     NameNode *nn;
  854.  
  855.     for (nn = GetHead(&FList); nn; nn = GetSucc(&nn->n_Node)) {
  856.         if (IsMask(nn->n_IsType) == IS_CFILE) {
  857.         HandleCFile(nn, fc);
  858.         }
  859.         if (NoAsm == 0 && IsMask(nn->n_IsType) == IS_AFILE) {
  860.         HandleAFile(nn, fc);
  861.         }
  862.     }
  863.     }
  864.  
  865.     /*
  866.      *    Link objects into executable
  867.      */
  868.  
  869.     if (NoLink == 0) {
  870.     char *lfile;
  871.  
  872.     lfile = DoPrelink();
  873.     if (lfile)
  874.         PushTmpFile(lfile);
  875.     DoLink(lfile);
  876.     if (lfile) {
  877.         PopTmpFile(lfile);
  878.         remove(lfile);
  879.         free(lfile);
  880.     }
  881.     }
  882.     exit(ExitCode);
  883. }
  884.  
  885. void
  886. AddFile(ptr)
  887. char *ptr;
  888. {
  889.     char *t = Tailer(ptr);
  890.  
  891.     if (strncmp(t, "a", 1) == 0) {
  892.     AddName(&FList, NULL, ptr, IS_AFILE);
  893.     } else
  894.     if (strncmp(t, "o", 1) == 0) {
  895.     AddName(&FList, NULL, ptr, IS_OFILE);
  896.     } else
  897.     if (strncmp(t, "l", 1) == 0) {
  898.     AddName(&FList, NULL, ptr, IS_OFILE);
  899.     } else {
  900.     AddName(&FList, NULL, ptr, IS_CFILE);
  901.     }
  902. }
  903.  
  904. DoCompile_Dice(in, out)
  905. char *in;
  906. char *out;
  907. {
  908.     char *qq = "";
  909.     char *cptmp = TmpFileName(".i");
  910.     char *code = (SmallCode) ? " -mc" : " -mC";
  911.     char *data = (SmallData) ? " -md" : " -mD";
  912.     char *rc = qq;
  913.     char *absdata;
  914.     char *concode;
  915.     char *res  = (ResOpt) ? " -r" : qq;
  916.     char *verb = (Verbose) ? " -v" : qq;
  917.     char *optsect = (AltSectOpt) ? " -S" : qq;
  918.     char *protoonly = (ProtoOnlyOpt) ? " -proto" : qq;
  919.     char *prof = (ProfOpt) ? " -prof" : qq;
  920.     char *mc68020 = (MC68020Opt) ? " -020" : qq;
  921.     char *mc68881 = (MC68881Opt) ? " -881" : qq;
  922.     char *piopt;
  923.     char *ffp = (FFPOpt) ? " -ffp" : qq;
  924.     char *genstack = (GenStackOpt) ? " -gs" : qq;
  925.     char *genlink  = (GenLinkOpt) ? " -gl" : qq;
  926.     char *slashopt = (SlashSlashOpt) ? " -//" : qq;
  927.     char *forkopt = (ForkOpt) ? " -fork" : qq;
  928.     char *unixcomopt = (UnixCommonOpt) ? " -mu" : qq;
  929.     char *asmopt = (NoAsm) ? " -a" : qq;
  930.     char *intopt = (IntOpt[0]) ? " -int" : qq;
  931.  
  932.     switch(RegCallOpt) {
  933.     case 1:
  934.     rc = " -mr";
  935.     break;
  936.     case 2:
  937.     rc = " -mR";
  938.     break;
  939.     case 3:
  940.     rc = " -mRR";
  941.     break;
  942.     case 4:
  943.     rc = " -mRRX";
  944.     break;
  945.     case 5:
  946.     rc = " -mRRY";
  947.     break;
  948.     }
  949.  
  950.     switch(ConstCode) {
  951.     case 1:
  952.     concode = " -ms";
  953.     break;
  954.     case 2:
  955.     concode = " -mS";
  956.     break;
  957.     default:
  958.     concode = qq;
  959.     break;
  960.     }
  961.  
  962.     switch(AbsData) {
  963.     case 1:
  964.     absdata = " -mw";
  965.     break;
  966.     case 2:
  967.     absdata = " -ma";
  968.     break;
  969.     default:
  970.     absdata = qq;
  971.     break;
  972.     }
  973.  
  974.     if (PIOpt) {
  975.     if (ResOpt)
  976.         piopt = " -pr";
  977.     else
  978.         piopt = " -pi";
  979.     res = qq;
  980.     absdata = qq;
  981.     code = qq;
  982.     data = qq;
  983.     } else {
  984.     piopt = qq;
  985.     }
  986.  
  987.     PushTmpFile(cptmp);
  988.     sprintf(Buf, "%s %s -o %s%s%s%s%s",
  989.     DCPP, in, cptmp, ErrOptStr, OptListToStr(&CppOptList),
  990.     ffp, slashopt
  991.     );
  992.     run_cmd(in, Buf);
  993.     sprintf(Buf, "%s %s -o %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
  994.     DC1, cptmp, out, code, data, rc, res, verb,
  995.     optsect, protoonly, prof, concode, absdata, piopt, ErrOptStr,
  996.     mc68020, mc68881, ffp, genstack, genlink, forkopt, unixcomopt,
  997.     asmopt, intopt, IntOpt,
  998.     DebugOpts
  999.     );
  1000.     run_cmd(in, Buf);
  1001.     PopTmpFile(cptmp);
  1002.     remove(cptmp);
  1003.     free(cptmp);
  1004.     return(0);
  1005. }
  1006.  
  1007. DoAssemble_Dice(cpath, in, out)
  1008. char *cpath;
  1009. char *in;
  1010. char *out;
  1011. {
  1012.     short n;
  1013.  
  1014.     n = sprintf(Buf, "%s -o%s %s%s", DAS, out, in, ErrOptStr);
  1015.     if (cpath)
  1016.     sprintf(Buf+n, " -N%s", cpath);
  1017.     run_cmd(cpath, Buf);
  1018.     return(0);
  1019. }
  1020.  
  1021. char *
  1022. DoPrelink_Dice(void)
  1023. {
  1024.     NameNode *nn;
  1025.     char *ltmp = TmpFileName(".lnk");
  1026.     FILE *fi = fopen(ltmp, "w");
  1027.  
  1028.     if (fi == NULL) {
  1029.     fprintf(stderr, "DCC: couldn't create %s\n", ltmp);
  1030.     exit(20);
  1031.     }
  1032.  
  1033.     for (nn = GetHead(&FList); nn; nn = GetSucc(&nn->n_Node)) {
  1034.     if (IsMask(nn->n_IsType) == IS_OFILE) {
  1035.         fputs(nn->n_In, fi);
  1036.         putc('\n', fi);
  1037.     }
  1038.     }
  1039.     while (nn = (NameNode *)RemHead(&LList)) {
  1040.     fputs(nn->n_In, fi);
  1041.     putc('\n', fi);
  1042.     }
  1043.  
  1044.     /*
  1045.      *    only small-data version of auto.lib is supported currently
  1046.      */
  1047.  
  1048.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  1049.     fprintf(fi, "%s%s.lib", CLib, CLibApp);
  1050.     fprintf(fi, " %s%s%s.lib %sautos.lib\n",
  1051.         AmigaLib, ALibOS, ALibApp, DLib
  1052.     );
  1053.     }
  1054.     fclose(fi);
  1055.     return(ltmp);
  1056. }
  1057.  
  1058. /*
  1059.  *  dlib:x.o is a special trailer for any autoinit code (in section autoinit,
  1060.  *  code)
  1061.  *
  1062.  *  This section is called in sequence just before main() with ac, av pushed on
  1063.  *  the stack.    The idea is that any module may reference an autoinit section to
  1064.  *  automatically initialize certain aspects of itself without requiring a call
  1065.  *  from the main program.
  1066.  */
  1067.  
  1068. DoLink_Dice(lfile)
  1069. char *lfile;
  1070. {
  1071.     char *qq = "";
  1072.     char *co = " ";
  1073.     char *ro = mergestr(DLib, "x.o");
  1074.     char *symopt = (SymOpt) ? " -s" : qq;
  1075.     char *resopt = (ResOpt) ? " -r" : qq;
  1076.     char *fragopt= (FragOpt) ? " -frag" : qq;
  1077.     char *chipopt= (ChipOpt) ? " -chip" : qq;
  1078.     char *postfix= qq;
  1079.     char *piopt;
  1080.     char absdata[20];
  1081.     char *verb = (Verbose) ? " -v" : qq;
  1082.  
  1083.     if (DLinkPostFixOpt) {
  1084.     static char PostFix[sizeof(CLibApp)+3];
  1085.     postfix = PostFix;
  1086.     sprintf(postfix, " -P%s", CLibApp);
  1087.     }
  1088.  
  1089.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  1090.     co = SCode[(short)((PIOpt << 1) | ResOpt)];
  1091.     }
  1092.  
  1093.     if (AbsData) {
  1094.     sprintf(absdata, " -ma 0x%lx", AbsDataStart);
  1095.     } else {
  1096.     absdata[0] = 0;
  1097.     }
  1098.  
  1099.     if (PIOpt) {
  1100.     if (ResOpt)
  1101.         piopt = " -pr";
  1102.     else
  1103.         piopt = " -pi";
  1104.     resopt = qq;
  1105.     if (AbsData) {
  1106.         absdata[0] = 0;
  1107.         puts("Warning: cannot mix -pi and -ma/-mw");
  1108.     }
  1109.     } else {
  1110.     piopt = qq;
  1111.     }
  1112.     if (FragOpt) {
  1113.     if (ResOpt) {
  1114.         puts("Warning: cannot use -frag with -r");
  1115.         fragopt = qq;
  1116.     }
  1117.     }
  1118.  
  1119.     sprintf(Buf, "%s %s @%s %s -o %s%s%s%s%s%s%s%s%s%s%s%s",
  1120.     DLINK, co, lfile, ro, OutFile,
  1121.     symopt,
  1122.     resopt,
  1123.     fragopt,
  1124.     piopt,
  1125.     absdata,
  1126.     postfix,
  1127.     chipopt,
  1128.     OptListToStr(&LinkOptList),
  1129.     ErrOptStr,
  1130.     DebugOpts,
  1131.     verb
  1132.     );
  1133.     run_cmd("", Buf);
  1134.     free(ro);
  1135.  
  1136.     /*
  1137.      * Delete temporary objects
  1138.      */
  1139.  
  1140.     {
  1141.     NameNode *nn;
  1142.  
  1143.         for (nn = GetHead(&FList); nn; nn = GetSucc(&nn->n_Node)) {
  1144.         if (nn->n_IsType & IS_TMP)
  1145.         remove(nn->n_In);
  1146.     }
  1147.     }
  1148.     return(0);
  1149. }
  1150.  
  1151.  
  1152.  
  1153. void
  1154. help(code)
  1155. {
  1156. #ifdef _DCC
  1157.     printf("%s%s\n", Ident, DCopyright);
  1158. #endif
  1159.     exit(code);
  1160. }
  1161.  
  1162. char *
  1163. TmpFileName(tail)
  1164. char *tail;
  1165. {
  1166.     char *buf = malloc(strlen(TmpDir) + strlen(tail) + 32);
  1167.     char dummy = 0;
  1168.  
  1169.     sprintf(buf, "%s%06lx%s", TmpDir, (long)&dummy >> 8, tail);
  1170.     return(buf);
  1171. }
  1172.  
  1173. /*
  1174.  *  file    -    file to modify
  1175.  *  hdr     -    new directory path to put file
  1176.  *  tail    -    new suffix
  1177.  *
  1178.  */
  1179.  
  1180. char *
  1181. MungeFile(file, hdr, tail)
  1182. char *file;
  1183. char *hdr;
  1184. char *tail;
  1185. {
  1186.     char *name = malloc(strlen(file) + (hdr ? strlen(hdr) : 0) + (tail ? strlen(tail) : 0) + 2);
  1187.     char *ptr;
  1188.     short n = 0;
  1189.  
  1190.     /*
  1191.      *    Prepend header, replacing the absolute portion of the file
  1192.      */
  1193.  
  1194.     if (hdr) {
  1195.     if (ptr = strchr(file, ':'))
  1196.         file = ptr + 1;
  1197.     n += sprintf(name + n, "%s", hdr);
  1198.  
  1199.     if (n && name[n-1] != ':' && name[n-1] != '/')
  1200.         name[n++] = '/';
  1201.     }
  1202.  
  1203.     /*
  1204.      *    The file
  1205.      */
  1206.  
  1207.     if (tail && (ptr = strrchr(file, '.'))) {
  1208.     n += sprintf(name + n, "%.*s", ptr - file, file);
  1209.     } else {
  1210.     n += sprintf(name + n, "%s", file);
  1211.     }
  1212.  
  1213.     /*
  1214.      *    Trailer
  1215.      */
  1216.  
  1217.     if (tail) {
  1218.     n += sprintf(name + n, "%s", tail);
  1219.     }
  1220.     name[n] = 0;
  1221.     return(name);
  1222. }
  1223.  
  1224. void
  1225. AddName(List *list, char *tailifnone, char *file, short isType)
  1226. {
  1227.     NameNode *nn = malloc(sizeof(NameNode));
  1228.     short i;
  1229.  
  1230.     for (i = strlen(file) - 1; i >= 0 && file[i] != '.'; --i) {
  1231.     if (file[i] == '/' || file[i] == ':')
  1232.         i = 0;
  1233.     }
  1234.  
  1235.     if (i < 0 && tailifnone) {
  1236.     nn->n_In = malloc(strlen(file) + strlen(tailifnone) + 1);
  1237.     sprintf(nn->n_In, "%s%s", file, tailifnone);
  1238.     } else {
  1239.     nn->n_In = malloc(strlen(file) + 1);
  1240.     strcpy(nn->n_In, file);
  1241.     }
  1242.     nn->n_Out = NULL;
  1243.     nn->n_IsType= isType;
  1244.     AddTail(list, &nn->n_Node);
  1245. }
  1246.  
  1247. NameNode *
  1248. AddOpt(list, opt, body)
  1249. List *list;
  1250. char *opt;
  1251. char *body;
  1252. {
  1253.     NameNode *nn = malloc(sizeof(NameNode));
  1254.  
  1255.     nn->n_In = opt;
  1256.     nn->n_Out= body;
  1257.     AddTail(list, &nn->n_Node);
  1258.     return(nn);
  1259. }
  1260.  
  1261. char *
  1262. Tailer(ptr)
  1263. char *ptr;
  1264. {
  1265.     short i;
  1266.  
  1267.     for (i = strlen(ptr) - 1; i >= 0 && ptr[i] != '.'; --i);
  1268.     if (i < 0)
  1269.     return("");
  1270.     return(ptr + i + 1);
  1271. }
  1272.  
  1273. char *
  1274. XFilePart(ptr)
  1275. char *ptr;
  1276. {
  1277.     short i;
  1278.  
  1279.     for (i = strlen(ptr) - 1; i >= 0 && ptr[i] != ':' && ptr[i] != '/'; --i);
  1280.     ++i;
  1281.     return(ptr + i);
  1282. }
  1283.  
  1284. char *
  1285. OptListToStr(list)
  1286. List *list;
  1287. {
  1288.     static char Tmp[512];
  1289.     short i;
  1290.     NameNode *scan;
  1291.  
  1292.     i = 0;
  1293.     Tmp[0] = 0;
  1294.     for (scan = (NameNode *)list->lh_Head; scan != (NameNode *)&list->lh_Tail; scan = (NameNode *)scan->n_Node.ln_Succ) {
  1295.     sprintf(Tmp + i, " %s%s", scan->n_In, scan->n_Out);
  1296.     i += strlen(Tmp + i);
  1297.     }
  1298.     return(Tmp);
  1299. }
  1300.  
  1301. #ifdef AZLAT_COMPAT
  1302.  
  1303. char *
  1304. OptListToStr2(list, cvt)
  1305. List *list;
  1306. char *cvt;
  1307. {
  1308.     static char Tmp[512];
  1309.     short i;
  1310.     NameNode *scan;
  1311.  
  1312.     i = 0;
  1313.     for (scan = (NameNode *)list->lh_Head; scan != (NameNode *)&list->lh_Tail; scan = (NameNode *)scan->n_Node.ln_Succ) {
  1314.     sprintf(Tmp + i, " %s%s", scan->n_In, scan->n_Out);
  1315.     {
  1316.         char *ptr;
  1317.         for (ptr = cvt; *ptr; ptr += 2) {
  1318.         if (Tmp[i+2] == ptr[0])
  1319.             Tmp[i+2] = ptr[1];
  1320.         }
  1321.     }
  1322.     i += strlen(Tmp + i);
  1323.     }
  1324.     return(Tmp);
  1325. }
  1326.  
  1327. #endif
  1328.  
  1329. /*
  1330.  *  run_cmd(buf)    buf[-1] is valid for BCPL stuff, buf[-1] is
  1331.  *            long word aligned.
  1332.  */
  1333.  
  1334. #ifdef AMIGA
  1335.  
  1336. void
  1337. run_cmd(cfile, buf)
  1338. char *cfile;        /* REXX support */
  1339. char *buf;
  1340. {
  1341.     short i;
  1342.     short j = strlen(buf);
  1343.     int r;
  1344.  
  1345. #if 0
  1346.     if (ErrFile)
  1347.     fclose(stderr);
  1348. #endif
  1349.  
  1350.     /*
  1351.      *    top (hack to support REXX fix/continue)
  1352.      */
  1353.  
  1354. top:
  1355. /*    if (Verbose) */
  1356.     printf("%s\n", buf);
  1357.  
  1358.  
  1359. #if 0
  1360. #if INCLUDE_VERSION >= 36
  1361.     if (SysBase->lib_Version >= 36) {
  1362.     long seg;
  1363.     long lock = NULL;
  1364.  
  1365.     Process *proc = (Process *)FindTask(NULL);
  1366.     CLI *cli = BTOC(proc->pr_CLI, CLI);
  1367.     long oldCommandName;
  1368.  
  1369.     dbprintf(("cmd-begin\n"));
  1370.  
  1371.     for (i = 0; buf[i] && buf[i] != ' '; ++i)
  1372.         ;
  1373.     movmem(buf, CmdName + 1, i);
  1374.     CmdName[0] = i;
  1375.     CmdName[i+1] = 0;
  1376.  
  1377.     if (cli) {
  1378.         oldCommandName = (long)cli->cli_CommandName;
  1379.         cli->cli_CommandName = CTOB(CmdName);
  1380.     }
  1381.  
  1382.     if (seg = (long)FindSegment(CmdName + 1, 0L, 0)) {
  1383.         r = RunCommand(((long *)seg)[2], 16384, buf + i + 1, strlen(buf + i + 1));
  1384.     } else if ((lock = _SearchPath(CmdName + 1)) && (seg = LoadSegLock(lock, ""))) {
  1385.         r = RunCommand(seg, 16384, buf + i + 1, strlen(buf + i + 1));
  1386.         UnLoadSeg(seg);
  1387.     } else if ((lock = Lock("dcc:bin", SHARED_LOCK)) && (seg = LoadSegLock(lock, CmdName + 1))) {
  1388.         r = RunCommand(seg, 16384, buf + i + 1, strlen(buf + i + 1));
  1389.         UnLoadSeg(seg);
  1390.     } else {
  1391.         printf("Unable to find executable %s resident, via your path\n", CmdName + 1);
  1392.         printf("or in DCC:BIN!\n");
  1393.         r = 20;
  1394.     }
  1395.     if (lock)
  1396.         UnLock(lock);
  1397.     if (cli)
  1398.         cli->cli_CommandName = (BSTR)oldCommandName;
  1399.  
  1400.     dbprintf(("cmd-end\n"));
  1401.     } else {
  1402. #else
  1403.     {
  1404. #endif
  1405.  
  1406. #ifdef _DCC
  1407.     if (FastOpt == 0) {
  1408. #endif
  1409.         if (Execute(buf, NULL, Output()) != -1) {
  1410.         printf("Unable to Execute %s\n", buf);
  1411.         exit(20);
  1412.         }
  1413.         r = 0;
  1414.  
  1415. #ifdef _DCC
  1416.     } else {
  1417.         for (i = 0; buf[i] && buf[i] != ' '; ++i)
  1418.         ;
  1419.         buf[i] = 0;
  1420.         if (i != j) {
  1421.         for (++i; buf[i] == ' '; ++i)
  1422.             ;
  1423.         }
  1424.         r = exec_dcc(buf, buf + i);
  1425.     }
  1426. #endif
  1427.     }
  1428. #else
  1429.    r = 10;
  1430. #endif
  1431.     if (r)
  1432.     printf("Exit code %d\n", r);
  1433. #ifdef COMMERCIAL
  1434. #ifndef unix
  1435.     if (r && RexxOpt) {
  1436.     long rr = HandleErrorRexx(cfile, buf, r);
  1437.     if (rr == 2)
  1438.         goto top;
  1439.     }
  1440. #endif
  1441. #endif
  1442.     if (ExitCode < r)
  1443.     ExitCode = r;
  1444. printf("going to exit exitcode=%d\n", ExitCode);
  1445.     if (ExitCode > 5)
  1446.     exit(ExitCode);
  1447.  
  1448.     /*
  1449.      *    close and reopen file to 'sync' it
  1450.      */
  1451.  
  1452. #if 0
  1453.     if (r && ErrFile)
  1454.     freopen(ErrFile, "a", stderr);
  1455. #endif
  1456. }
  1457.  
  1458. #else
  1459.  
  1460. #include <sys/wait.h>
  1461.  
  1462. void
  1463. run_cmd(cfile, buf)
  1464. char *cfile;        /* REXX support */
  1465. char *buf;
  1466. {
  1467.     int r;
  1468.  
  1469.     if (Verbose)
  1470.     printf("%s\n", buf);
  1471.  
  1472.     if ((r = vfork()) == 0) {
  1473.     execlp("/bin/sh", "/bin/sh", "-c", buf, 0);
  1474.     exit(30);
  1475.     } else {
  1476.     union wait uwait;
  1477.     while (wait(&uwait) != r || WIFEXITED(uwait) == 0)
  1478.         ;
  1479.     r = uwait.w_retcode;
  1480.     }
  1481.  
  1482.     if (r)
  1483.     printf("Exit code %d\n", r);
  1484.     if (ExitCode < r)
  1485.     ExitCode = r;
  1486.     if (ExitCode > 5)
  1487.     exit(ExitCode);
  1488. }
  1489.  
  1490. #endif
  1491.  
  1492. #ifdef AMIGA
  1493.  
  1494. int
  1495. OutOfDate(in, out)
  1496. char *in;
  1497. char *out;
  1498. {
  1499.     static FIB *InFib;
  1500.     static FIB *OutFib;
  1501.     BPTR inLock, outLock;
  1502.     FIB *inFib;
  1503.     FIB *outFib;
  1504.     int r = 1;
  1505.  
  1506.     if (NewOpt == 0)
  1507.     return(1);
  1508.  
  1509.     if (InFib == NULL) {
  1510.     InFib = malloc(sizeof(FIB));
  1511.     OutFib = malloc(sizeof(FIB));
  1512.     }
  1513.     inFib = InFib;
  1514.     outFib = OutFib;
  1515.  
  1516.     if (inLock = Lock(in, SHARED_LOCK)) {
  1517.     if (outLock = Lock(out, SHARED_LOCK)) {
  1518.         if (Examine(inLock, inFib) && Examine(outLock, outFib)) {
  1519.         if (inFib->fib_Date.ds_Days < outFib->fib_Date.ds_Days)
  1520.             r = 0;
  1521.         else if (inFib->fib_Date.ds_Days == outFib->fib_Date.ds_Days) {
  1522.             if (inFib->fib_Date.ds_Minute < outFib->fib_Date.ds_Minute)
  1523.             r = 0;
  1524.             else if (inFib->fib_Date.ds_Minute == outFib->fib_Date.ds_Minute) {
  1525.             if (inFib->fib_Date.ds_Tick < outFib->fib_Date.ds_Tick)
  1526.                 r = 0;
  1527.             }
  1528.         }
  1529.         }
  1530.         UnLock(outLock);
  1531.     }
  1532.     UnLock(inLock);
  1533.     }
  1534.     return(r);
  1535. }
  1536.  
  1537. #else
  1538.  
  1539. int
  1540. OutOfDate(in, out)
  1541. char *in;
  1542. char *out;
  1543. {
  1544.     struct stat instat;
  1545.     struct stat outstat;
  1546.     int r = 1;
  1547.  
  1548.     if (NewOpt == 0)
  1549.     return(1);
  1550.  
  1551.     if (stat(in, &instat) == 0) {
  1552.     if (stat(out, &outstat) == 0) {
  1553.         if (instat.st_mtime < outstat.st_mtime)
  1554.         r = 0;
  1555.     }
  1556.     }
  1557.     return(r);
  1558. }
  1559.  
  1560. #endif
  1561.  
  1562. void
  1563. HandleCFile(nn, fc)
  1564. NameNode *nn;
  1565. int fc;
  1566. {
  1567.     char *asmName;
  1568.     char *objName;
  1569.  
  1570.     if (fc == 1 && OutFile && NoAsm)
  1571.     asmName = OutFile;
  1572.     else if (NoAsm)
  1573.     asmName = MungeFile(nn->n_In, OutDir, ".a");
  1574.     else
  1575.     asmName = MungeFile(XFilePart(nn->n_In), TmpDir, ".a");
  1576.  
  1577.     nn->n_IsType = IS_OFILE;
  1578.  
  1579.     if (fc == 1 && OutFile && NoLink) {
  1580.     objName = OutFile;
  1581.     } else if (NoLink) {
  1582.     objName = MungeFile(nn->n_In, OutDir, ".o");
  1583.     } else {
  1584.     objName = MungeFile(XFilePart(nn->n_In), TmpDir, ".o");
  1585.     nn->n_IsType |= IS_TMP;
  1586.     }
  1587.  
  1588.     if (NoAsm) {    /*  in -> asmName        */
  1589.     if (OutOfDate(nn->n_In, asmName))
  1590.         DoCompile(nn->n_In, asmName);
  1591.     } else {        /*  in -> asmName -> objName*/
  1592.     if (OutOfDate(nn->n_In, objName)) {
  1593.         PushTmpFile(asmName);
  1594.         if (NoIntermediateAssembly) {
  1595.         DoCompile(nn->n_In, objName);
  1596.         } else {
  1597.         DoCompile(nn->n_In, asmName);
  1598.         if (NoHeirOpt == 0)
  1599.             CreateObjPath(objName);
  1600.         DoAssemble(nn->n_In, asmName, objName);
  1601.         }
  1602.         PopTmpFile(asmName);
  1603.         remove(asmName);
  1604.     }
  1605.     }
  1606.     nn->n_In = strdup(objName);
  1607. }
  1608.  
  1609. void
  1610. HandleAFile(nn, fc)
  1611. NameNode *nn;
  1612. int fc;
  1613. {
  1614.     char *objName;
  1615.  
  1616.     nn->n_IsType = IS_OFILE;
  1617.  
  1618.     if (fc == 1 && OutFile && NoLink) {
  1619.     objName = OutFile;
  1620.     } else if (NoLink) {
  1621.     objName = MungeFile(nn->n_In, OutDir, ".o");
  1622.     } else {
  1623.     objName = MungeFile(XFilePart(nn->n_In), TmpDir, ".o");
  1624.     nn->n_IsType |= IS_TMP;
  1625.     }
  1626.  
  1627.     if (OutOfDate(nn->n_In, objName)) {
  1628.     if (NoHeirOpt == 0)
  1629.         CreateObjPath(objName);
  1630.     DoAssemble(NULL, nn->n_In, objName);
  1631.     }
  1632.     nn->n_In = strdup(objName);
  1633. }
  1634.  
  1635. void
  1636. PushTmpFile(name)
  1637. char *name;
  1638. {
  1639.     Node *node = malloc(sizeof(Node) + strlen(name) + 1);
  1640.     if (node == NULL) {
  1641.     puts("Ran out of memory!");
  1642.     exit(25);
  1643.     }
  1644.     node->ln_Name = (char *)(node + 1);
  1645.     strcpy(node->ln_Name, name);
  1646.     AddHead(&TmpList, node);
  1647. }
  1648.  
  1649. void
  1650. PopTmpFile(name)
  1651. char *name;
  1652. {
  1653.     Node *node = RemHead(&TmpList);
  1654.  
  1655.     if (node == NULL || strcmp(name, node->ln_Name) != 0) {
  1656.     puts("PopTmpFile: software error");
  1657.     exit(20);
  1658.     }
  1659.     free(node);
  1660. }
  1661.  
  1662. #ifdef AMIGA
  1663.  
  1664. long
  1665. LoadSegLock(lock, cmd)
  1666. long lock;
  1667. char *cmd;
  1668. {
  1669.     long oldLock;
  1670.     long seg;
  1671.  
  1672.     oldLock = CurrentDir(lock);
  1673.     seg = LoadSeg(cmd);
  1674.     CurrentDir(oldLock);
  1675.     return(seg);
  1676. }
  1677.  
  1678. #endif
  1679.  
  1680. void
  1681. DefaultOutName(void)
  1682. {
  1683.     NameNode *nn;
  1684.  
  1685.     /*
  1686.      *    if no output file name set and only one source file was specified,
  1687.      *    set output file name based on said file
  1688.      */
  1689.  
  1690.     if (OutFile == NULL) {
  1691.     OutFile = "a.out";
  1692.  
  1693.     if (nn = GetHead(&FList)) {
  1694.         /*if (GetSucc(&nn->n_Node) == NULL)*/ {
  1695.         char *ptr = strdup(nn->n_In);
  1696.         char *p0;
  1697.  
  1698.         if (p0 = strrchr(ptr, '.')) {
  1699.             *p0 = 0;
  1700.             OutFile = ptr;
  1701.         }
  1702.         }
  1703.     }
  1704.     }
  1705. }
  1706.  
  1707. /*
  1708.  *    AZTEC C, LATTICE C COMPATIBILITY OPTIONS
  1709.  */
  1710.  
  1711. #ifdef AZLAT_COMPAT
  1712.  
  1713. DoLink(lfile)
  1714. char *lfile;
  1715. {
  1716.     switch(CompilerOpt) {
  1717.     case DICE_C:
  1718.     return(DoLink_Dice(lfile));
  1719.     case LATTICE_C:
  1720.     return(DoLink_Lattice(lfile));
  1721.     case AZTEC_C:
  1722.     return(DoLink_Aztec(lfile));
  1723.     }
  1724. }
  1725.  
  1726. DoCompile(in, out)
  1727. char *in;
  1728. char *out;
  1729. {
  1730.     switch(CompilerOpt) {
  1731.     case DICE_C:
  1732.     return(DoCompile_Dice(in, out));
  1733.     case LATTICE_C:
  1734.     return(DoCompile_Lattice(in, out));
  1735.     case AZTEC_C:
  1736.     return(DoCompile_Aztec(in, out));
  1737.     }
  1738.     return(0);
  1739. }
  1740.  
  1741. DoAssemble(cfile, in, out)
  1742. char *cfile;
  1743. char *in;
  1744. char *out;
  1745. {
  1746.     switch(CompilerOpt) {
  1747.     case DICE_C:
  1748.     return(DoAssemble_Dice(cfile, in, out));
  1749.     case LATTICE_C:
  1750.     return(DoAssemble_Lattice(cfile, in, out));
  1751.     case AZTEC_C:
  1752.     return(DoAssemble_Aztec(cfile, in, out));
  1753.     }
  1754.     return(0);
  1755. }
  1756.  
  1757. char *
  1758. DoPrelink(void)
  1759. {
  1760.     switch(CompilerOpt) {
  1761.     case DICE_C:
  1762.     return(DoPrelink_Dice());
  1763.     case LATTICE_C:
  1764.     return(DoPrelink_Lattice());
  1765.     case AZTEC_C:
  1766.     return(DoPrelink_Aztec());
  1767.     }
  1768.     return(0);
  1769. }
  1770.  
  1771. /*
  1772.  *    ------------------------------------------------------------------
  1773.  */
  1774.  
  1775. DoCompile_Lattice(in, out)
  1776. char *in;
  1777. char *out;
  1778. {
  1779.     char *qq = "";
  1780.     char *cptmp = TmpFileName(".i");
  1781.     char *data = (SmallData) ? qq : " -b0";
  1782.  
  1783.     sprintf(Buf, "lc -o%s %s %s %s",
  1784.     out, OptListToStr2(&CppOptList, "DdIi"), data, in
  1785.     );
  1786.     run_cmd(in, Buf);
  1787.  
  1788.     free(cptmp);
  1789.     return(0);
  1790. }
  1791.  
  1792. DoAssemble_Lattice(cfile, in, out)
  1793. char *cfile;
  1794. char *in;
  1795. char *out;
  1796. {
  1797.     sprintf(Buf, "asm -o%s %s", out, in);
  1798.     run_cmd(cfile, Buf);
  1799.     return(0);
  1800. }
  1801.  
  1802. char *
  1803. DoPrelink_Lattice(void)
  1804. {
  1805.     NameNode *nn;
  1806.     char *ltmp = TmpFileName(".lnk");
  1807.     FILE *fi = fopen(ltmp, "w");
  1808.     short libs = 0;
  1809.  
  1810.     if (fi == NULL) {
  1811.     fprintf(stderr, "DCC: couldn't create %s\n", ltmp);
  1812.     exit(20);
  1813.     }
  1814.  
  1815.     for (nn = GetHead(&FList); nn; nn = GetSucc(&nn->n_Node)) {
  1816.     if (IsMask(nn->n_IsType) == IS_OFILE) {
  1817.         fputs(nn->n_In, fi);
  1818.         putc('\n', fi);
  1819.     }
  1820.     }
  1821.  
  1822.     while (nn = (NameNode *)RemHead(&LList)) {
  1823.     if (libs == 0) {
  1824.         fprintf(fi, "LIB ");
  1825.         libs = 1;
  1826.     }
  1827.     fputs(nn->n_In, fi);
  1828.     putc('\n', fi);
  1829.     }
  1830.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  1831.     if (libs == 0) {
  1832.         fprintf(fi, "LIB ");
  1833.         libs = 1;
  1834.     }
  1835.     fprintf(fi, "lib:lc.lib lib:amiga.lib\n");
  1836.     }
  1837.  
  1838.     fclose(fi);
  1839.     return(ltmp);
  1840. }
  1841.  
  1842. DoLink_Lattice(lfile)
  1843. char *lfile;
  1844. {
  1845.     char *qq = "";
  1846.     char *co = " ";
  1847.     char *symopt = (SymOpt) ? " ADDSYM" : qq;
  1848.     char *scopt = (SmallData) ? " SD" : qq;
  1849.     char *sdopt = (SmallCode) ? " SC" : qq;
  1850.  
  1851.     if (RomOpt == 0 && NoDefaultLibs == 0) {       /*  RomOpt PIOpt ResOpt */
  1852.     static char *SCode[] = { "lib:c.o",         /*    0      0      0   */
  1853.                  "lib:cres.o",      /*    0      0      1   */
  1854.                  "lib:c.o",         /*    0      1      0   */
  1855.                  "lib:cres.o"       /*    0      1      1   */
  1856.                    };
  1857.     co = SCode[(short)((PIOpt << 1) | ResOpt)];
  1858.     }
  1859.  
  1860.     sprintf(Buf, "BLink from %s with %s to %s%s%s%s",
  1861.     co, lfile, OutFile, symopt, scopt, sdopt
  1862.     );
  1863.     run_cmd("", Buf);
  1864.     return(0);
  1865. }
  1866.  
  1867. /*
  1868.  *  ---------------------------------------------------------------------
  1869.  */
  1870.  
  1871. DoCompile_Aztec(in, out)
  1872. char *in;
  1873. char *out;
  1874. {
  1875.     char *qq = "";
  1876.     char *cptmp = TmpFileName(".i");
  1877.     char *data = (SmallData) ? qq : qq;
  1878.  
  1879.     sprintf(Buf, "cc %s %s %s -o %s",
  1880.     OptListToStr2(&CppOptList, ""), data, in, out
  1881.     );
  1882.     run_cmd(in, Buf);
  1883.  
  1884.     free(cptmp);
  1885.     return(0);
  1886. }
  1887.  
  1888. DoAssemble_Aztec(cfile, in, out)
  1889. char *cfile;
  1890. char *in;
  1891. char *out;
  1892. {
  1893.     sprintf(Buf, "as %s -o %s", in, out);
  1894.     run_cmd(cfile, Buf);
  1895.     return(0);
  1896. }
  1897.  
  1898. char *
  1899. DoPrelink_Aztec(void)
  1900. {
  1901.     NameNode *nn;
  1902.     char *ltmp = TmpFileName(".lnk");
  1903.     FILE *fi = fopen(ltmp, "w");
  1904.  
  1905.     if (fi == NULL) {
  1906.     fprintf(stderr, "DCC: couldn't create %s\n", ltmp);
  1907.     exit(20);
  1908.     }
  1909.  
  1910.     for (nn = GetHead(&FList); nn; nn = GetSucc(&nn->n_Node)) {
  1911.     if (IsMask(nn->n_IsType) == IS_OFILE) {
  1912.         fputs(nn->n_In, fi);
  1913.         putc('\n', fi);
  1914.     }
  1915.     }
  1916.     while (nn = (NameNode *)RemHead(&LList)) {
  1917.     fputs(nn->n_In, fi);
  1918.     putc('\n', fi);
  1919.     }
  1920.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  1921.     fprintf(fi, "-lc\n");
  1922.     }
  1923.     fclose(fi);
  1924.     return(ltmp);
  1925. }
  1926.  
  1927. DoLink_Aztec(lfile)
  1928. char *lfile;
  1929. {
  1930.     char *qq = "";
  1931.  
  1932.     sprintf(Buf, "ln -f %s -o %s", lfile, OutFile);
  1933.     run_cmd("", Buf);
  1934.     return(0);
  1935. }
  1936.  
  1937. #endif
  1938.  
  1939. void
  1940. OrderApp(buf)
  1941. char *buf;
  1942. {
  1943.     short i;
  1944.     short c;
  1945.     char sort[26];
  1946.  
  1947.     setmem(sort, sizeof(sort), 0);
  1948.     for (i = 0; c = buf[i]; ++i) {
  1949.     if (c >= 'a' && c <= 'z')
  1950.         sort[c-'a'] = 1;
  1951.     }
  1952.     for (i = sizeof(sort) - 1, c = 0; i >= 0; --i) {
  1953.     if (sort[i])
  1954.         buf[c++] = i + 'a';
  1955.     }
  1956.     buf[c] = 0;
  1957. }
  1958.  
  1959. void
  1960. AddLibApp(char *buf, char c)
  1961. {
  1962.     short i = strlen(buf);
  1963.  
  1964.     if (strchr(buf, c) == NULL) {
  1965.     buf[i+0] = c;
  1966.     buf[i+1] = 0;
  1967.     }
  1968. }
  1969.  
  1970. void
  1971. DelLibApp(char *buf, char c)
  1972. {
  1973.     char *ptr;
  1974.  
  1975.     if (ptr = strchr(buf, c))
  1976.     movmem(ptr + 1, ptr, strlen(ptr + 1) + 1);
  1977. }
  1978.  
  1979. char *
  1980. PathConvert(path)
  1981. char *path;
  1982. {
  1983. #ifdef _DCC
  1984.     if (strstr(path, "./") || strstr(path, "../"))
  1985.     return(strdup(UnixToAmigaPath(path)));
  1986. #endif
  1987.     return(path);
  1988. }
  1989.  
  1990. void *
  1991. GetHead(list)
  1992. List *list;
  1993. {
  1994.     if (list->lh_Head != (Node *)&list->lh_Tail)
  1995.     return(list->lh_Head);
  1996.     return(NULL);
  1997. }
  1998.  
  1999. void *
  2000. GetSucc(node)
  2001. Node *node;
  2002. {
  2003.     Node *r = node->ln_Succ;
  2004.  
  2005.     if (r->ln_Succ)
  2006.     return(r);
  2007.     return(NULL);
  2008. }
  2009.  
  2010. char *
  2011. mergestr(const char *s1, const char *s2)
  2012. {
  2013.     char *ptr = malloc(strlen(s1) + strlen(s2) + 1);
  2014.     sprintf(ptr, "%s%s", s1, s2);
  2015.     return(ptr);
  2016. }
  2017.  
  2018. #ifdef COMMERCIAL
  2019. #ifndef unix
  2020.  
  2021. /*
  2022.  *  HANDLEERRORREXX()
  2023.  *
  2024.  *  Scan DCC:CONFIG/DCC.CONFIG to obtain REXX command execution information
  2025.  *  then attempt to run the appropriate command.  If the REXX script returns
  2026.  *  2 we retry the compilation.  If the REXX script returns anything else
  2027.  *  we abort.
  2028.  *
  2029.  *  cfile can be "", indicating no source file available to handle error(s)
  2030.  */
  2031.  
  2032. int
  2033. HandleErrorRexx(cfile, cmdbuf, rc)
  2034. char *cfile;
  2035. char *cmdbuf;
  2036. int rc;
  2037. {
  2038.     FILE *fi;
  2039.     int r = -1;
  2040.     char *buf;
  2041.     char *fullPath;
  2042.     char *cmdName = "cmd=";
  2043.     char *portName = "port=";
  2044.     char *rexxCmdName = "rexxcmd=";
  2045.     char *curDirPath = FullPathOf("");
  2046.  
  2047. #if 0
  2048.     if (buf = malloc(256)) {
  2049.     /*
  2050.      *  obtain full path to cFile, if present
  2051.      */
  2052.  
  2053.     if (cfile[0]) {
  2054.         fullPath = FullPathOf(cfile);
  2055.     } else {
  2056.         fullPath = strdup("");
  2057.         cmdName = "linkcmd=";
  2058.         portName = "linkport=";
  2059.         rexxCmdName = "linkrexxcmd=";
  2060.     }
  2061.     if (fullPath) {
  2062.         /*
  2063.          *    open the config file
  2064.          */
  2065.  
  2066.         if (fi = fopen("DCC:CONFIG/DCC.CONFIG", "r")) {
  2067.         char *cmd = NULL;
  2068.         char *port = NULL;
  2069.         char *rexxcmd = NULL;
  2070.  
  2071.         while (fgets(buf, 256, fi)) {
  2072.             if (strnicmp(buf, cmdName, strlen(cmdName)) == 0)
  2073.             cmd = ScanReplace(buf + strlen(cmdName), fullPath, ErrFile, curDirPath);
  2074.             else if (strnicmp(buf, portName, strlen(portName)) == 0)
  2075.             port = ScanReplace(buf + strlen(portName), fullPath, ErrFile, curDirPath);
  2076.             else if (strnicmp(buf, rexxCmdName, strlen(rexxCmdName)) == 0)
  2077.             rexxcmd= ScanReplace(buf + strlen(rexxCmdName), fullPath, ErrFile, curDirPath);
  2078.         }
  2079.         fclose(fi);
  2080.  
  2081.         if (Verbose) {
  2082.             printf("cmd=%s port=%s rexxcmd=%s file=%s\n",
  2083.             (cmd ? cmd : ""),
  2084.             (port ? port : ""),
  2085.             (rexxcmd ? rexxcmd : ""),
  2086.             fullPath
  2087.             );
  2088.         }
  2089.  
  2090.         Forbid();
  2091.         if (port && rexxcmd) {
  2092.             /*
  2093.             *  Attempt to run the CLI command that starts up the
  2094.             *  editor (or whatever)
  2095.             */
  2096.  
  2097.             {
  2098.             short retry = 0;
  2099.  
  2100.             while (FindPort(port) == NULL && retry < 5 && cmd) {
  2101.                 if (retry == 0)
  2102.                 Execute(cmd, NULL, NULL);
  2103.                 Delay(50);
  2104.                 ++retry;
  2105.             }
  2106.             }
  2107.  
  2108.             /*
  2109.             *  If port found place a REXX command directly to the port
  2110.             */
  2111.  
  2112.             if (FindPort(port)) {
  2113.             long ec;
  2114.  
  2115.             Permit();
  2116.             r = PlaceRexxCommandDirect(NULL,port,rexxcmd,NULL,&ec);
  2117.             Forbid();
  2118.             if (Verbose)
  2119.                 printf("R = %d %d\n", r, ec);
  2120.             ec = r;
  2121.             }
  2122.         } else if (cmd) {
  2123.             Execute(cmd, NULL, NULL);
  2124.         }
  2125.         Permit();
  2126.         if (cmd)
  2127.             free(cmd);
  2128.         if (port)
  2129.             free(port);
  2130.         if (rexxcmd)
  2131.             free(rexxcmd);
  2132.         } else {
  2133.         printf("can't open dcc:config/dcc.config\n");
  2134.         }
  2135.         free(fullPath);
  2136.     }
  2137.     free(buf);
  2138.     }
  2139.     return(r);
  2140. #else
  2141.     return(0);
  2142. #endif
  2143. }
  2144.  
  2145. DoRexxCommand(msg, port, arg0, pres)
  2146. void *msg;
  2147. struct MsgPort *port;
  2148. char *arg0;
  2149. char **pres;
  2150. {
  2151.     return(20);
  2152. }
  2153.  
  2154. /*
  2155.  *  Handle %f/%e/%d/%n replacement in dcc.config
  2156.  */
  2157.  
  2158. char *
  2159. ScanReplace(buf, cFile, errFile, curDirPath)
  2160. char *buf;
  2161. char *cFile;
  2162. char *errFile;
  2163. char *curDirPath;
  2164. {
  2165.     char *s;
  2166.     char *rbuf;
  2167.     short i;
  2168.     short len;
  2169.     short dpindex;  /*    directory part index, char after directory  */
  2170.     short fpindex;  /*    file part index, char beginning file        */
  2171.  
  2172.     /*
  2173.      *    Split cFile into directory part and file part
  2174.      */
  2175.  
  2176.     for (dpindex = strlen(cFile) - 1; dpindex >= 0; --dpindex) {
  2177.     if ((cFile[dpindex] == ':') || (cFile[dpindex] == '/'))
  2178.         break;
  2179.     }
  2180.     ++dpindex;
  2181.     fpindex = dpindex;
  2182.  
  2183.     if (cFile[fpindex] == ':')
  2184.     ++fpindex;
  2185.  
  2186.     /*
  2187.      *    Actual scan
  2188.      */
  2189.  
  2190.     while (*buf == ' ' || *buf == '\t')
  2191.     ++buf;
  2192.     rbuf = NULL;
  2193.     for (i = 0; i < 2; ++i) {
  2194.     len = 0;
  2195.  
  2196.     for (s = buf; *s; ++s) {
  2197.         if (*s == '%') {
  2198.         ++s;
  2199.         switch(*s) {
  2200.         case 'f':       /*  %f - source file    */
  2201.             if (rbuf)
  2202.             sprintf(rbuf + len, "%s", cFile);
  2203.             len += strlen(cFile);
  2204.             continue;
  2205.         case 'e':       /*  %e - error file     */
  2206.             if (rbuf)
  2207.             sprintf(rbuf + len, "%s", errFile);
  2208.             len += strlen(errFile);
  2209.             continue;
  2210.         case 'd':
  2211.             if (rbuf)
  2212.             sprintf(rbuf + len, "%.*s", dpindex, cFile);
  2213.             len += dpindex;
  2214.             continue;
  2215.         case 'n':
  2216.             if (rbuf)
  2217.             sprintf(rbuf + len, "%s", cFile + fpindex);
  2218.             len += strlen(cFile + fpindex);
  2219.             continue;
  2220.         case 'c':
  2221.             if (rbuf)
  2222.             sprintf(rbuf + len, "%s", curDirPath);
  2223.             len += strlen(curDirPath);
  2224.             continue;
  2225.         case '0':
  2226.         case '1':
  2227.         case '2':
  2228.         case '3':
  2229.         case '4':
  2230.         case '5':
  2231.         case '6':
  2232.         case '7':
  2233.         case '8':
  2234.         case '9':
  2235.             {
  2236.             char *aptr = RexxReplace[*s - '0'];
  2237.  
  2238.             if (aptr == NULL)
  2239.                 aptr = "?";
  2240.             if (rbuf)
  2241.                 sprintf(rbuf + len, "%s", aptr);
  2242.             len += strlen(aptr);
  2243.             }
  2244.             continue;
  2245.         }
  2246.         --s;
  2247.         }
  2248.         if (*s == '\n')
  2249.         continue;
  2250.         if (rbuf)
  2251.         rbuf[len] = *s;
  2252.         ++len;
  2253.     }
  2254.     if (i == 0)
  2255.         rbuf = malloc(len + 1);
  2256.     }
  2257.     if (rbuf)
  2258.     rbuf[len] = 0;
  2259.     else
  2260.     rbuf = strdup("");
  2261.     return(rbuf);
  2262. }
  2263.  
  2264. char *
  2265. FullPathOf(file)
  2266. char *file;
  2267. {
  2268.     BPTR lock;
  2269.     BPTR dlock;
  2270.     __aligned FIB fib;
  2271.     char *s1 = strdup(file);
  2272.     char *s2;
  2273.     short i = -1;
  2274.  
  2275.     if (lock = Lock(file, SHARED_LOCK)) {
  2276.     if (Examine(lock, &fib)) {
  2277.         free(s1);
  2278.         s1 = strdup(fib.fib_FileName);
  2279.         while (dlock = ParentDir(lock)) {
  2280.         UnLock(lock);
  2281.         lock = dlock;
  2282.         if (Examine(lock, &fib)) {
  2283.             s2 = malloc(strlen(s1) + strlen(fib.fib_FileName) + 2);
  2284.             sprintf(s2, "%s/%s", fib.fib_FileName, s1);
  2285.             free(s1);
  2286.             s1 = s2;
  2287.             i = strlen(fib.fib_FileName);
  2288.         }
  2289.         }
  2290.     }
  2291.     UnLock(lock);
  2292.     if (i)
  2293.         s1[i] = ':';
  2294.     }
  2295.     return(s1);
  2296. }
  2297.  
  2298. #endif
  2299. #endif
  2300.  
  2301.  
  2302.